#ifndef CSCRIPTMANAGER_H
#define CSCRIPTMANAGER_H

#include <QObject>
#include <QAction>
#include <QJSEngine>
#include <QFileSystemWatcher>
#include <QTimer>
#include <QMap>
#include <QWebSocket>

#include "../network/cwebsocketserver.h"
#include "../network/networkframemanager.h"
#include "../common/singleton.h"

#define IDD_JS_MESSAGE_LOG              1000          // 日志信息
#define IDD_JS_MESSAGE_UPDATESOURCES    1001          // 更新脚本
#define IDD_JS_MESSAGE_GETRESOURCELIST  1002          // 得到资源列表
#define IDD_JS_MESSAGE_GETRESOURCEDATA  1003          // 得到资源数据
#define IDD_JS_MESSAGE_AUTH_FAIL        1004          // 权限不对

class CJsManager : public QObject , public NetworkFrameManager
{
    Q_OBJECT

public:
    Q_INVOKABLE CJsManager(QWidget *parent = nullptr);
    ~CJsManager();

    /// 设置当前系统工作目录
    void setCurrentWorkingPath(QString ppath);
    /// 得到当前系统工作目录
    inline QString getCurrentWorkingPath(void) { return m_currentWorkingPath; }
    /// 设置当前脚本注册的dll所在目录
    inline void setRegisterDllPath(QString ppath) { m_currentRegisterDllPath = ppath; }
    /// 得到当前脚本注册的dll所在目录
    inline QString getRegisterDllPath(void) { return m_currentRegisterDllPath; }
    /// 初始化系统
    bool init_system(QString workingpath,QString regdllpath="",int serverport=-1);
    /// 卸载系统
    void clean_system(void);
    /// 添加一个管理员账号
    void addSysManager(QString name,QString pwd);
    /// 删除指定的管理员
    void delSysManager(QString name);
    /// 清除所有的管理员
    void clearSysManagers(void);
    /// 设置是否启用权限管理
    inline void EnableAuthManage(bool isEnable) { m_IsEnableAuthManager = isEnable; }
    /// 得到是否启用权限管理
    inline bool isEnableAuthManage(void) { return m_IsEnableAuthManager; }
    /// 发送日志信息
    Q_INVOKABLE void Log(QString msg, QString type="info",bool isPrint=true,bool isSend=true,bool isLog=true,bool isProg=false);

    /// 从指定文件中导入脚本并执行
    bool js_loadscriptstring_callback(QString scriptfilepath);
    /// 初始脚本系统
    void js_setup_callback(void);
    ///注册一个新的对象
    QJSValue RegisterNewObject(QString objName,QObject *newobject,bool isCppOwnership=false);

    /// 处理网络字符串消息
    virtual void OnProcessNetText(QWebSocket *conn,QString mes);
    /// 处理网络二进制消息
    virtual void OnProcessNetBinary(QWebSocket *conn,QByteArray &data);
    /// 处理一个新的连接到达
    virtual void OnProcessConnectedNetMes(QWebSocket *conn);
    /// 处理一个连接关闭
    virtual void OnProcessDisconnectedNetMes(QWebSocket *conn);

private:
    /// 得到脚本系统所使用的资源列表
    void onProcessNetProjectGetInfo(QWebSocket *conn,QJsonObject &mesObj);
    /// 得到指定资源的内容
    void onProcessNetProjectGetInfoContent(QWebSocket *conn,QJsonObject &mesObj);
    /// 更新脚本资源
    void onProcessNetProjectUpdateResource(QWebSocket *conn,QJsonObject &mesObj);

    /// 注册所有用到的函数
    void reg_all2jss(void);

public slots:
    void WorkingdirectoryChange(const QString &path);
    void WorkingdirectoryChanged(void);

private:
    QJSEngine m_JSEngine;                             /**< 脚本引擎 */
    QString m_currentWorkingPath;                     /**< 当前系统工作目录 */
    QString m_currentRegisterDllPath;                 /**< 当前脚本注册的dll所在目录 */
    bool m_isLoadScript;                              /**< 有些情况下需要资源全部加装完成后再导入 */
    QFileSystemWatcher m_pSystemWorkingPathWatcher;   /**< 用于监控系统工作目录以便于重新加载脚本 */
    QTimer *m_SystemWorkingPathTimer;                 /**< 用于过滤工作目录不停改变的情况,我们只需要最后的改变 */
    CWebSocketServer m_WebSocketServer;               /**< 网络支持 */
    QMap<QString,QString> m_AuthManager;              /**< 权限管理 */
    bool m_IsEnableAuthManager;                       /**< 是否启用权限管理 */
};

#endif // CSCRIPTMANAGER_H
